﻿//#include "stdafx.h"																											//VS2017删除
//	^(?([^\r\n])\s)*\r?$\r?\n              ( 正则表达式，删除空白行）
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define prints(...) do { fprintf(stderr, __VA_ARGS__); } while(0)
#define Assert(EXPRESSION, CODE, ...) do { if(!(EXPRESSION)) { \
	prints("\nFile %s, line %d.\nReturned error: ", __FILE__, __LINE__);\
	prints(__VA_ARGS__);\
	return CODE; } } while(0)
#define STRINGBUFF 1024
typedef struct
{
	double isp, ist, ish, itp, itt, ith, osp, ost, osh, otp, ott, oth;
} Blade;
typedef struct
{
	Blade rb, sb;
	int stagename;
} Stage;
typedef struct
{
	Stage stages[64];
	int componentname, stagenumber;
} Component;
typedef struct
{
	Component components[64];
	int componentnumber;
	int pointname;
} Point;
typedef struct
{
	Point points[64];
	int pointnumber;
} Data;
int datareset(Data *data) {
	memset(data, 0, sizeof(Data));
	return 0;
}
void fileread(Data*data, FILE*in)
{
	const char *BLADEFMT[4] = { "%*31c%d%d", "%*31c%d%d%d%d", "%*31c%d%d%d%d%d%d", "%*31c%d%d%d%d%d%d%d%d" };
	const char *DOUBLEFMT[4] = { "%*31c%lg%lg", "%*31c%lg%lg%lg%lg", "%*31c%lg%lg%lg%lg%lg%lg", "%*31c%lg%lg%lg%lg%lg%lg%lg%lg" };
	datareset(data);
	char line[STRINGBUFF];
	const char*POINT_START = " COMPONENT NO. ",
		*POINT_END = "                                              KW TURBINE-GENERATOR UNIT",
		*POINT_NAME = "1CALCULATION FOR POINT",
		*COMP_START = "                                     GROUP INPUT DATA",
		*COMP_END = " GROSS OUTPUT",
		*COMPGEO_START = "                                                             BLADING GEOMETRY",
		*COMPGEO_END = "                                                             BLADING PERFORMANCE",
		*COMPPERFOR_START = " THERMODYNAMIC PARAMETERS",
		*COMPPERFOR_END = "                                                             LOSS COEFFICIENTS",
		*COMP_NAME = " COMPONENT",
		*OUT_STA_ENTHA = " STATIC ENTHALPY";
#define FINDKEYWORD(KEYWORD)   !strncmp(KEYWORD,line,strlen(KEYWORD))
	while (fgets(line, STRINGBUFF, in))
	{
		if (FINDKEYWORD(POINT_START) && strncmp(" COMPONENT NO. =", line, 16))                                                                                                 //工况起点
		{
			Point *ppoint = &data->points[data->pointnumber];
			while (fgets(line, STRINGBUFF, in))
			{
				if (FINDKEYWORD(POINT_END))                                                                                                                                        //工况终点
				{
					++data[0].pointnumber;
					break;
				}
				if (FINDKEYWORD(POINT_NAME))																                     //pointname
					sscanf(line, "%*22c%d", &ppoint->pointname);
				if (FINDKEYWORD(COMP_START))                                                          //componnet 开始
				{
					int stagenumber = 0, itemp = 0;
					Component *pcomponent = &ppoint->components[ppoint->componentnumber];
					while (fgets(line, STRINGBUFF, in))
					{
						if (FINDKEYWORD(COMP_END))                                                                                          //componnet 结束
						{
							ppoint->componentnumber++;
							break;
						}
						if (FINDKEYWORD(COMPGEO_START))                            //geometry开始
						{
							while (fgets(line, STRINGBUFF, in))
							{
								if (FINDKEYWORD(COMPGEO_END))        break;        //geometry结束
								if (!strncmp(line, " SOLUTION STATION", 17))        stagenumber += sscanf(line, BLADEFMT[3], &itemp, &itemp, &itemp, &itemp, &itemp, &itemp, &itemp, &itemp, &itemp);
							}
							pcomponent->stagenumber = (stagenumber - 2) / 2;                                                                                       //计算级数
						}
						if (FINDKEYWORD(COMPPERFOR_START))																                     //performance开始
						{
							int stagenumber = 0;
							while (fgets(line, STRINGBUFF, in))
							{
								if (FINDKEYWORD(COMPPERFOR_END))         break;        //performance结束
								if (FINDKEYWORD(COMP_NAME) && (pcomponent->componentname == 0))                                                                         //读取级组名称
								{
									sscanf(line, "%*15c%d", &pcomponent->componentname);
								}
#define  SSBLADEITEM(KEYWORD,TARGET)  do{if(FINDKEYWORD(KEYWORD))\
									{sscanf(line, DOUBLEFMT[3],\
								    &pcomponent->stages[stagenumber].rb.TARGET,\
                                    &pcomponent->stages[stagenumber].sb.TARGET, \
                                    &pcomponent->stages[stagenumber + 1].rb.TARGET,\
                                    &pcomponent->stages[stagenumber + 1].sb.TARGET,\
	                                &pcomponent->stages[stagenumber + 2].rb.TARGET, \
                                    &pcomponent->stages[stagenumber + 2].sb.TARGET, \
                                    &pcomponent->stages[stagenumber + 3].rb.TARGET, \
                                    &pcomponent->stages[stagenumber + 3].sb.TARGET);\
                                    stagenumber += 4;}\
							} while(0)
								SSBLADEITEM(OUT_STA_ENTHA, osh);
#undef SSBLADEITEM  
							}
						}
					}
				}
			}
		}
	}
#undef FINDKEYWORD
}
void fileprint(Data*data, FILE*out)
{
	for (const Point *ppoint = data->points; ppoint < (data->points + data->pointnumber); ppoint++)
	{
		int stagecount = 1;
		fprintf(out, "POINTNAME,%d\n", ppoint->pointname);
		fprintf(out, "STAGENUMBER,");
		for (const Component *pcomponent = (ppoint->components + ppoint->componentnumber) - 1; pcomponent >= ppoint->components; pcomponent--)
		{
			for (const Stage *pstage = (pcomponent->stages + pcomponent->stagenumber) - 1; pstage >= pcomponent->stages; pstage--)
			{
				fprintf(out, "%d,", stagecount++);
			}
		}
		fprintf(out, "\n");
		fprintf(out, "所属级组,");
		for (const Component *pcomponent = (ppoint->components + ppoint->componentnumber) - 1; pcomponent >= ppoint->components; pcomponent--)
		{
			for (const Stage *pstage = (pcomponent->stages + pcomponent->stagenumber) - 1; pstage >= pcomponent->stages; pstage--)
			{
				fprintf(out, "%d,", pcomponent->componentname);
			}
		}
		fprintf(out, "\n");
		fprintf(out, "动叶出口静焓,");
		for (const Component *pcomponent = (ppoint->components + ppoint->componentnumber) - 1; pcomponent >= ppoint->components; pcomponent--)
		{
			for (const Stage *pstage = (pcomponent->stages + pcomponent->stagenumber) - 1; pstage >= pcomponent->stages; pstage--)
			{
				fprintf(out, "%lg,", pstage->rb.osh);
			}
		}
		fprintf(out, "\n");
	}
}
template<class Data, class Func>
int file_do(const char *path, bool read_mode, Data data, Func func) {
	printf(read_mode ? "<< %s\n" : ">> %s\n", path);
	FILE *fp = fopen(path, read_mode ? "r" : "w");
	Assert(fp, -1, read_mode ? "wrong with inputfile:%s" : "wrong with outputfile:%s", path);
	func(data, fp);
	fclose(fp);
	return 0;
}
int main(int argc, char* argv[])
{
	if (argc == 3)
	{
		Data *data = (Data*)malloc(sizeof(Data));
		file_do(argv[1], true, data, fileread);
		file_do(argv[2], false, data, fileprint);
		free(data);
	}
	else Assert(argc == 3, -1, "\nUsage:8086tran inputfileaddress outputfileaddress\n");
	return 0;
}
//test1